package com.kaia.shoebox.fragment;

import java.sql.SQLException;
import java.util.List;

import com.j256.ormlite.stmt.PreparedQuery;
import com.kaia.shoebox.R;
import com.kaia.shoebox.adapter.OnDatabaseActionListener;
import com.kaia.shoebox.adapter.ShoeboxListAdapter;
import com.kaia.shoebox.db.dao.Importance;
import com.kaia.shoebox.db.dao.TodoItem;

import android.app.Activity;
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Loader;
import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import android.widget.SearchView.OnQueryTextListener;

public abstract class BaseListFragment extends ListFragment implements
		LoaderCallbacks<List<TodoItem>>, OnQueryTextListener {

	protected ShoeboxListAdapter mAdapter;

	private OnDatabaseActionListener mListener;

	private static final String TAG = BaseListFragment.class.getSimpleName();

	// ------------------------------------------------------------------
	// Lifecycle
	// ------------------------------------------------------------------

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);

		try {
			mListener = (OnDatabaseActionListener) activity;
		} catch (ClassCastException e) {
			throw new ClassCastException(activity.toString()
					+ " must implement OnListChangedListener");
		}
	}

	@Override
	public void onActivityCreated(Bundle savedInstanceState) {
		super.onActivityCreated(savedInstanceState);

		mAdapter = new ShoeboxListAdapter(getActivity());
		setListAdapter(mAdapter);

		setHasOptionsMenu(true);
		setListShown(false);

		ListView list = getListView();
		list.setTextFilterEnabled(true);
		registerForContextMenu(list);

		Log.i(TAG, "Requesting data for list");
		getLoaderManager().initLoader(0, null, this);
	}

	@Override
	public void onResume() {
		super.onResume();
		mAdapter.notifyDataSetChanged();
	}

	// ------------------------------------------------------------------
	// Overrides
	// ------------------------------------------------------------------

	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		MenuItem item = menu.add("Search");
		item.setIcon(android.R.drawable.ic_menu_search);
		item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
		SearchView sv = new SearchView(getActivity());
		sv.setOnQueryTextListener(this);
		item.setActionView(sv);
	}

	@Override
	public Loader<List<TodoItem>> onCreateLoader(int id, Bundle args) {
		Loader<List<TodoItem>> loader = null;

		try {
			PreparedQuery<TodoItem> query = mListener.getQueryBuilder().where()
					.ne(TodoItem.IMPORTANCE, Importance.DONE).prepare();
			loader = mListener.getLoader(query);

		} catch (SQLException e) {
			Log.e(TAG, "Error while querying the database", e);
			Toast.makeText(getActivity(),
					"There was an error while populating the list",
					Toast.LENGTH_LONG).show();
		}

		return loader;
	}

	@Override
	public void onLoadFinished(Loader<List<TodoItem>> loader,
			List<TodoItem> data) {
		Log.d(TAG, "onLoadFinished");
		mAdapter.clear();
		mAdapter.addAll(data);

		if (isResumed()) {
			setListShown(true);
		} else {
			setListShownNoAnimation(true);
		}
	}

	@Override
	public void onLoaderReset(Loader<List<TodoItem>> loader) {
		mAdapter.clear();
	}

	@Override
	public boolean onQueryTextChange(String newText) {
		if (!TextUtils.isEmpty(newText)) {
			this.getListView().setFilterText(newText);
		} else {
			this.getListView().clearTextFilter();
		}
		return true;
	}

	@Override
	public boolean onQueryTextSubmit(String query) {
		return onQueryTextChange(query);
	}

	// ------------------------------------------------------------------
	// Utility Methods
	// ------------------------------------------------------------------

	public void deleteTodo(int itemPos) {

		final TodoItem item = mAdapter.getItem(itemPos);

		Log.i(TAG, "Deleting item: " + item.getId());

		final Animation animation = AnimationUtils.loadAnimation(getActivity(),
				R.anim.fade_out);
		View rowView = getListView().getChildAt(itemPos);
		rowView.startAnimation(animation);

		Handler handler = new Handler();
		handler.postDelayed(new Runnable() {

			public void run() {
				if (mListener.deleteTodo(item)) {
					mAdapter.remove(item);
				}
			}
		}, 1000);

	}
	
	public void addNewTodo(TodoItem item) {
		mAdapter.add(item);
	}

	public void sortByDueDate() {
		mAdapter.sortByDueDate();
	}

	public void sortByCreationDate() {
		mAdapter.sortByCreatedDate();
	}

	public void sortByImportance() {
		mAdapter.sortByImportance();
	}
	
	// ------------------------------------------------------------------
	// Abstract Methods
	// ------------------------------------------------------------------

}
